package com.comp6521.project01;

import java.util.Vector;

public class Merger {

	private Vector<String> sortedLists;
	private String destDir;
	
	public Merger(Vector<String> sortedLists, String destDir) {
		this.sortedLists = sortedLists;
		this.destDir = destDir;
	}
	
	public void merge() {
		
		// define the size of input buffer
		// define the size of output buffer
		// create an array of n input buffers
		// create one output buffer
		// associate each sortedlist with an input buffer
		// associate the output buffer with a result file
		// merge
		
		final int inputBufferSize  = 4*1024; // 4 KB 
		final int outputBufferSize = 4*1024; // 4 KB
		
		InputBuffer[] inputBuffers = new InputBuffer[sortedLists.size()];
		for (int i = 0; i < sortedLists.size(); ++i)
		{
			inputBuffers[i] = new InputBuffer(inputBufferSize, sortedLists.get(i));
		}
		OutputBuffer   outputBuffer = new OutputBuffer(outputBufferSize, destDir + "\\result.dat");
		
		// compare the heads of the input, and select the smallest
		// write the smallest to the output buffer
		// stop when all input buffers are empty; then flush the output buffer
		Integer []selection = new Integer[sortedLists.size()];
		boolean done = false;
		
		while (!done) 
		{
			for (int i=0; i < sortedLists.size(); ++i)
			{
				selection[i] = inputBuffers[i].getFirst();
			}
			
			Integer index = selectMin(selection);
			if (index == null)
			{
				done = true;
				outputBuffer.flush();
			}
			else
			{
				outputBuffer.add(inputBuffers[index].popTop());
			}
		}
		
		// close
		for (int i = 0; i < sortedLists.size(); ++i)
		{
			inputBuffers[i].close();
		}
		outputBuffer.close();
	}

	private Integer selectMin(Integer[] selection) {
		
		Integer index = null;
		
		// find the first item that is not null and assign it to index
		for (Integer i=0; i < selection.length; ++i)
		{
			if(selection[i] != null )
			{
				index = i;
				break;
			}
		}
		
		// find index of min
		for (Integer i=index; i != null && i < selection.length; ++i)
		{
			if(selection[i] != null && selection[i] < selection[index])
				index = i;
		}
		return index;
	}
}
